package com.ssm.platform.controller;

import com.ssm.basis.service.exception.CustomException;
import com.ssm.basis.service.office.WordUtil;
import com.ssm.basis.web.aop.lock.RepeatRequest;
import com.ssm.platform.pojo.vo.DictTranslateTestVo;
import com.ssm.platform.service.IDynamicDataSourceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Profile;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.validation.constraints.Pattern;
import java.util.HashMap;

import static com.ssm.basis.service.exception.CustomExceptionEnum.LOGIN_EXCEPTION;
import static java.nio.charset.StandardCharsets.UTF_8;

@Validated
@Profile("dev")
@Tag(name = "测试")
@RestController
@RequiredArgsConstructor
@RequestMapping("test")
public class TestController {
    final IDynamicDataSourceService dynamicDataSourceService;

    @Operation(summary = "@Secured")
    // @PreFilter("active == 'dev'")
    @PostMapping("security")
    @Secured({"ROLE_ANONYMOUS", "ROLE_ADMIN", "ROLE_USER"})
    // @PreAuthorize("hasRole('ADMIN')") // 自动加 ROLE_ 前缀
    // @PostAuthorize("hasAuthority('ROLE_ADMIN')") // 不自动加前缀
    // @PreAuthorize("hasAnyAuthority('SCOPE_openid', 'ROLE_USER')") // 不自动加前缀，多个角色，当前用户有其中一种即可，scope基于客户端应用，role基于用户
    public Object security(@RequestParam String active) {
        return "security";
    }

    @Operation(summary = "@Secured")
    @Secured({"ROLE_ANONYMOUS"})
    @GetMapping("security1")
    public Object security1() {
        return "security";
    }

    @Operation(summary = "exception")
    @GetMapping("exception")
    public Object exception() {
        return 10 / 0;
    }

    @Operation(summary = "customException")
    @GetMapping("customException")
    public Object customException() {
        throw new CustomException(LOGIN_EXCEPTION);
    }

    @Operation(summary = "who")
    @GetMapping("who")
    public Object user(@Parameter(hidden = true) @AuthenticationPrincipal User user) {
        return user;
    }

    @Operation(summary = "Cacheable")
    @GetMapping("cache")
    @Cacheable("piDecimals")
    public Object cache(String param) {
        return "@Cacheable " + param;
    }

    @Operation(summary = "字典翻译")
    @GetMapping("dictTranslate")
    public Object dictTranslate() {
        return new DictTranslateTestVo[]{
                new DictTranslateTestVo("1", "1", new DictTranslateTestVo.TestVo("0", "0"))
        };
    }

    @Parameters({
            @Parameter(name = "id", description = "单独的请求参数", in = ParameterIn.QUERY),
            @Parameter(name = "name", description = "单独的请求参数", in = ParameterIn.HEADER)
    })
    @Operation(summary = "多数据保存")
    @GetMapping("DynamicDataSource")
    void save() {
        dynamicDataSourceService.save();
    }

    @Operation(summary = "void")
    @GetMapping("void")
    void voidTest() {
    }

    @RepeatRequest
    @Operation(summary = "重复请求")
    @GetMapping("repeatRequest")
    String repeatRequest(String name, Integer age) {
        return "ok";
    }

    @Operation(summary = "word")
    @ResponseStatus(HttpStatus.CREATED)
    @GetMapping(path = "word", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<StreamingResponseBody> export(@Pattern(regexp = "[^.]+", message = "不能有后缀") String fileName) {
        return ResponseEntity.status(HttpStatus.CREATED)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .headers(h -> h.setContentDisposition(ContentDisposition.attachment().filename(fileName + ".docx", UTF_8).build()))
                // .header(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment().filename(fileName, UTF_8).build().toString())
                .body(body -> StreamUtils.copy(WordUtil.createWordBytes("templates/word.docx", new HashMap<String, Object>() {{
                    put("name", "张三<w:br/>张三");
                }}), body));
    }
}
